package com.zzh.lib.core.utils;


import android.text.TextUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * Created by ZZH on 2022/8/1.
 *
 * @Date: 2022/8/1
 * @Email: zzh_hz@126.com
 * @QQ: 1299234582
 * @Author: zzh
 * @Description: 数学操作工具类。对一些Double ,Float 加减乘除限制比较严格，
 * 避免0.999999或者是0.000001这种情况。
 */
public class HMathUtils {

    private HMathUtils() {
    }

    /**
     * 两个数相加
     * arg1 + arg2 =  result
     *
     * @param arg1 double
     * @param arg2 double
     * @return 和
     */
    public static String add(double arg1, double arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        BigDecimal addResult = bigArg1.add(bigArg2);
        return addResult.toString();
    }

    public static BigDecimal add(String arg1, double arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.add(bigArg2);
    }

    public static BigDecimal add(double arg1, String arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.add(bigArg2);
    }

    public static BigDecimal add(String arg1, String arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.add(bigArg2);
    }

    public static BigDecimal addX(double arg1, double arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.add(bigArg2);
    }

    public static BigDecimal addX(String arg1, double arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.add(bigArg2);
    }

    public static BigDecimal addX(double arg1, String arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.add(bigArg2);
    }

    public static BigDecimal addX(String arg1, String arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.add(bigArg2);
    }

    /**
     * 两个数值相减
     * arg1 - arg2 = result
     *
     * @param arg1 double
     * @param arg2 double
     * @return 差
     */
    public static String subtract(double arg1, double arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        BigDecimal subResult = bigArg1.subtract(bigArg2);
        return subResult.toString();
    }

    public static String subtract(String arg1, double arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        BigDecimal subResult = bigArg1.subtract(bigArg2);
        return subResult.toString();
    }

    public static String subtract(double arg1, String arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        BigDecimal subResult = bigArg1.subtract(bigArg2);
        return subResult.toString();
    }

    public static String subtract(String arg1, String arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        BigDecimal subResult = bigArg1.subtract(bigArg2);
        return subResult.toString();
    }

    public static BigDecimal subtractX(String arg1, String arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.subtract(bigArg2);
    }

    public static BigDecimal subtractX(double arg1, String arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.subtract(bigArg2);
    }

    public static BigDecimal subtractX(String arg1, double arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.subtract(bigArg2);
    }

    public static BigDecimal subtractX(double arg1, double arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.subtract(bigArg2);
    }

    /**
     * 两个数值相乘
     * arg1 x arg2 = result
     *
     * @param arg1 double
     * @param arg2 double
     * @return 积
     */
    public static String multiply(double arg1, double arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        BigDecimal subResult = bigArg1.multiply(bigArg2);
        return subResult.toString();
    }

    public static String multiply(String arg1, double arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        BigDecimal subResult = bigArg1.multiply(bigArg2);
        return subResult.toString();
    }

    public static String multiply(double arg1, String arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        BigDecimal subResult = bigArg1.multiply(bigArg2);
        return subResult.toString();
    }

    public static String multiply(String arg1, String arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        BigDecimal subResult = bigArg1.multiply(bigArg2);
        return subResult.toString();
    }

    public static BigDecimal multiplyX(double arg1, double arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.multiply(bigArg2);
    }

    public static BigDecimal multiplyX(String arg1, double arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.multiply(bigArg2);
    }

    public static BigDecimal multiplyX(double arg1, String arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.multiply(bigArg2);
    }

    public static BigDecimal multiplyX(String arg1, String arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.multiply(bigArg2);
    }

    /**
     * 两个数值相除
     * arg1 / arg2 = result
     *
     * @param arg1 double
     * @param arg2 double
     * @return 商
     */
    public static String divide(double arg1, double arg2, int scale, RoundingMode roundingMode) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        BigDecimal subResult = bigArg1.divide(bigArg2, scale, roundingMode);
        return subResult.toString();
    }

    public static String divide(double arg1, double arg2) {
        return divide(arg1, arg2, 2, RoundingMode.HALF_UP);

    }

    public static String divide(String arg1, double arg2, int scale, RoundingMode roundingMode) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        BigDecimal subResult = bigArg1.divide(bigArg2, scale, roundingMode);
        return subResult.toString();
    }

    public static String divide(String arg1, double arg2) {
        return divide(arg1, arg2, 2, RoundingMode.HALF_UP);
    }

    public static String divide(double arg1, String arg2, int scale, RoundingMode roundingMode) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        BigDecimal subResult = bigArg1.divide(bigArg2, scale, roundingMode);
        return subResult.toString();
    }

    public static String divide(double arg1, String arg2) {
        return divide(arg1, arg2, 2, RoundingMode.HALF_UP);
    }

    public static String divide(String arg1, String arg2, int scale, RoundingMode roundingMode) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        BigDecimal subResult = bigArg1.divide(bigArg2, scale, roundingMode);
        return subResult.toString();
    }

    public static String divide(String arg1, String arg2) {
        return divide(arg1, arg2, 2, RoundingMode.HALF_UP);
    }

    public static BigDecimal divideX(double arg1, double arg2, int scale, RoundingMode roundingMode) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.divide(bigArg2, scale, roundingMode);
    }

    public static BigDecimal divideX(double arg1, double arg2) {
        return divideX(arg1, arg2, 2, RoundingMode.HALF_UP);
    }

    public static BigDecimal divideX(String arg1, double arg2, int scale, RoundingMode roundingMode) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.divide(bigArg2, scale, roundingMode);
    }

    public static BigDecimal divideX(String arg1, double arg2) {
        return divideX(arg1, arg2, 2, RoundingMode.HALF_UP);
    }

    public static BigDecimal divideX(double arg1, String arg2, int scale, RoundingMode roundingMode) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.divide(bigArg2, scale, roundingMode);
    }

    public static BigDecimal divideX(double arg1, String arg2) {
        return divideX(arg1, arg2, 2, RoundingMode.HALF_UP);
    }

    public static BigDecimal divideX(String arg1, String arg2, int scale, RoundingMode roundingMode) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return bigArg1.divide(bigArg2, scale, roundingMode);
    }

    public static BigDecimal divideX(String arg1, String arg2) {
        return divideX(arg1, arg2, 2, RoundingMode.HALF_UP);
    }

    /**
     * 比较大小
     * 前一个参数是否大于第二个参数。
     *
     * @param arg1 参数1
     * @param arg2 参数2
     * @return true，参数1 > 参数2
     */
    public static boolean greatThan(String arg1, String arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return greatThan(bigArg1, bigArg2);
    }

    /**
     * {@link #greatThan(String, String)}
     *
     * @param bigArg1 BigDecimal
     * @param bigArg2 BigDecimal
     * @return true，参数1 > 参数2
     */
    public static boolean greatThan(BigDecimal bigArg1, BigDecimal bigArg2) {
        return bigArg1.compareTo(bigArg2) > 0;
    }

    /**
     * 比较大小
     * 前一个参数是否小于第二个参数。
     *
     * @param arg1 参数1
     * @param arg2 参数2
     * @return true，参数1 < 参数2
     */
    public static boolean lessThan(String arg1, String arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return lessThan(bigArg1, bigArg2);
    }

    /**
     * {@link #lessThan(String, String)}
     */
    public static boolean lessThan(BigDecimal bigArg1, BigDecimal bigArg2) {
        return bigArg1.compareTo(bigArg2) < 0;
    }

    /**
     * 比较大小
     * 前一个参数是否等于第二个参数。
     *
     * @param arg1 参数1
     * @param arg2 参数2
     * @return true，参数1 == 参数2
     */
    public static boolean equalsThan(String arg1, String arg2) {
        BigDecimal bigArg1 = new BigDecimal(arg1);
        BigDecimal bigArg2 = new BigDecimal(arg2);
        return equalsThan(bigArg1, bigArg2);
    }

    /**
     * 是否相等
     * {@link #equalsThan(String, String)}
     */
    public static boolean equalsThan(BigDecimal bigArg1, BigDecimal bigArg2) {
        return bigArg1.compareTo(bigArg2) == 0;
    }

    /**
     * string 2 int 转换
     *
     * @param doubleValue 字符串
     * @return int类型的数据
     */
    public static int safeParseInt(String intValue) {
        return safeParseInt(intValue, 0);
    }

    /**
     * string 2 int 转换
     *
     * @param intValue     字符串
     * @param defaultValue 默认值
     * @return int
     */
    public static int safeParseInt(String intValue, int defaultValue) {
        if (TextUtils.isEmpty(intValue)) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(intValue);
        } catch (Exception ex) {
            return defaultValue;
        }

    }

    /**
     * string 2 long 转换。
     * "" 转 long类型，是 0L
     *
     * @param longValue 字符串
     * @return long 类型的数据,如果转换异常则返回 0
     */
    public static long safeParseLong(String longValue) {
        return safeParseLong(longValue, 0L);
    }

    /**
     * string 2 long 转换。 "" 转 long类型，是 0L
     *
     * @param longValue    字符串
     * @param defaultValue 默认值
     * @return long
     */
    public static long safeParseLong(String longValue, long defaultValue) {
        if (TextUtils.isEmpty(longValue)) {
            return defaultValue;
        }
        try {
            return Long.parseLong(longValue);
        } catch (Exception ex) {
            return defaultValue;
        }
    }

    /**
     * string 2 double 转换
     *
     * @param doubleValue 字符串
     * @return int 类型的数据
     */
    public static double safeParseDouble(String doubleValue) {
        return safeParseDouble(doubleValue, 0d);

    }

    /**
     * string 2 double 转换
     *
     * @param doubleValue  字符串
     * @param defaultValue 默认值
     * @return double
     */
    public static double safeParseDouble(String doubleValue, double defaultValue) {
        if (TextUtils.isEmpty(doubleValue)) {
            return defaultValue;
        }
        try {
            return Double.parseDouble(doubleValue);
        } catch (Exception ex) {
            return defaultValue;
        }

    }

    /**
     * string 2 float 转换
     *
     * @param floatValue 字符串
     * @return int 类型的数据
     */
    public static float safeParseFloat(String floatValue) {
        if (TextUtils.isEmpty(floatValue)) {
            return 0;
        }
        try {
            return Float.parseFloat(floatValue);
        } catch (Exception ex) {
            return 0;
        }
    }

    /**
     * string 2 float 转换
     *
     * @param floatValue   字符串
     * @param defaultValue 默认值
     * @return float
     */
    public static float safeParseFloat(String floatValue, float defaultValue) {
        if (TextUtils.isEmpty(floatValue)) {
            return defaultValue;
        }
        try {
            return Float.parseFloat(floatValue);
        } catch (Exception ex) {
            return defaultValue;
        }
    }
}
